package com.ruoyi.common.utils.file;

import cn.hutool.core.text.StrBuilder;
import ws.schild.jave.Encoder;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;
import ws.schild.jave.encode.VideoAttributes;
import ws.schild.jave.filtergraphs.OverlayWatermark;
import ws.schild.jave.filters.helpers.OverlayLocation;
import ws.schild.jave.info.MultimediaInfo;
import ws.schild.jave.info.VideoInfo;
import ws.schild.jave.process.ProcessLocator;
import ws.schild.jave.process.ProcessWrapper;
import ws.schild.jave.process.ffmpeg.DefaultFFMPEGLocator;

import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 视频操作类
 *
 * @author Licl
 * @date 2020-12-15
 */
public class VideoUtils {

    /**
     * 视频加图片水印
     *
     * @param sourceFile
     * @param distFile
     * @param waterMark
     * @throws EncoderException
     */
    public static void codecToMp4WithWaterMark(String sourceFile, String distFile, String waterMark) throws EncoderException {
        File sourceVideo = new File(sourceFile);
        File watermark = new File(waterMark);
        AudioAttributes audioAttr = new AudioAttributes();
        audioAttr.setChannels(2);
        VideoAttributes videoAttr = new VideoAttributes();
        videoAttr.setCodec("libx264");

        OverlayWatermark videoFilter = new OverlayWatermark(watermark, OverlayLocation.BOTTOM_RIGHT, -10, -10);
        String expression = videoFilter.getExpression();
        System.out.println(expression);

        videoAttr.addFilter(videoFilter);
        EncodingAttributes encAttr = new EncodingAttributes();
        encAttr.setVideoAttributes(videoAttr);
        encAttr.setAudioAttributes(audioAttr);
        File target = new File(distFile);
        MultimediaObject multimediaObject = new MultimediaObject(sourceVideo);
        Encoder encoder = new Encoder();
        encoder.encode(multimediaObject, target, encAttr);
    }

    /**
     * 截取视频中某一帧作为图片
     *
     * @param videoPath
     * @param imagePath
     * @return
     */
    public static boolean getVideoProcessImage(String videoPath, String imagePath) {
        long times = System.currentTimeMillis();
        File videoSource = new File(videoPath);
        File imageTarget = new File(imagePath);
        MultimediaObject object = new MultimediaObject(videoSource);
        try {
            MultimediaInfo multimediaInfo = object.getInfo();
            VideoInfo videoInfo = multimediaInfo.getVideo();
            VideoAttributes video = new VideoAttributes();
            video.setCodec("png");
            video.setSize(videoInfo.getSize());
            EncodingAttributes attrs = new EncodingAttributes();
            //VideoAttributes attrs = ecodeAttrs.getVideoAttributes().get();
            attrs.setOutputFormat("image2");
            attrs.setOffset(1f);//设置偏移位置，即开始转码位置（11秒）
            attrs.setDuration(0.01f);//设置转码持续时间（1秒）
            attrs.setVideoAttributes(video);
            Encoder encoder = new Encoder();
            encoder.encode(object, imageTarget, attrs);
            return true;
        } catch (EncoderException e) {
            e.printStackTrace();
            return false;
        }
    }


    // -i D:\Downloads\duang.mp4 -i D:\Downloads\jiuling_logo_min.png -filter_complex overlay
    // D:\Downloads\video\duang111.mp4
    public static void videoInsertWatermark(String filePath, String distFile, String watermark) {
        ProcessLocator processLocator = new DefaultFFMPEGLocator();
        ProcessWrapper ffmpeg = processLocator.createExecutor();
        ffmpeg.addArgument("-i");
        ffmpeg.addArgument(filePath);
        ffmpeg.addArgument("-vf");
        ffmpeg.addArgument("\"movie= '");
        ffmpeg.addArgument(watermark);
        ffmpeg.addArgument("' [watermark]; [in][watermark] overlay=main_w-overlay_w-10:10 [out]\"");
        ffmpeg.addArgument(distFile);
        try {
            ffmpeg.execute();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ffmpeg.destroy();
        }
//        //获取进程
//        Runtime run = Runtime.getRuntime();
//        Process p = null;
//        String command = ffmpegPath +" -i "+ filePath +" -vf " +
//                "\"movie= '"+ watermark +"' [watermark]; [in][watermark] overlay=main_w-overlay_w-10:10 [out]\" " +
//                distFile;
//        System.out.println(command);
//        //执行doc命令
//        try {
//            p = run.exec(command);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    // -i D:\Downloads\duang.mp4 -i D:\Downloads\jiuling_logo_min.png -filter_complex overlay D:\Downloads\video\duang111.mp4
    public static void videoInsertWatermark(String filePath, String watermark) {
        ProcessLocator processLocator = new DefaultFFMPEGLocator();
        ProcessWrapper ffmpeg = processLocator.createExecutor();
        ffmpeg.addArgument("-i");
        ffmpeg.addArgument(filePath);
        ffmpeg.addArgument("-i");
        ffmpeg.addArgument(watermark);
        ffmpeg.addArgument("-filter_complex");
        ffmpeg.addArgument("overlay");
        ffmpeg.addArgument(filePath);
        try {
            ffmpeg.execute();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ffmpeg.destroy();
        }
    }

    public static long getVideoTime(String path) {
        ProcessLocator processLocator = new DefaultFFMPEGLocator();
        ProcessWrapper ffmpeg = processLocator.createExecutor();
        ffmpeg.addArgument("-i");
        ffmpeg.addArgument(path);
        try {
            ffmpeg.execute();
            InputStream inputStream = ffmpeg.getErrorStream();
            InputStreamReader streamReader = new InputStreamReader(inputStream);
            BufferedReader br = new BufferedReader(streamReader);
            String line = "";
            StrBuilder strBuilder = new StrBuilder();
            while ((line = br.readLine()) != null) {
                strBuilder.append(line);
            }
            br.close();
            streamReader.close();
            inputStream.close();
            String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
            Pattern pattern = Pattern.compile(regexDuration);
            String input = strBuilder.toString();
            System.out.println("---------------------------------------------------------");
            System.out.println(input);
            Matcher m = pattern.matcher(input);
            if (m.find()) {
                int time = getTimelen(m.group(1));
                System.out.println("视频时长：" + time + "s , 开始时间：" + m.group(2) + ", 比特率：" + m.group(3) + "kb/s");
                return time;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ffmpeg.destroy();
        }
        return 0;
    }

    private static int getTimelen(String timelen) {
        int min = 0;
        String[] strs = timelen.split(":");
        if (strs[0].compareTo("0") > 0) {
            // 秒
            min += Integer.parseInt(strs[0]) * 60 * 60;
        }
        if (strs[1].compareTo("0") > 0) {
            min += Integer.parseInt(strs[1]) * 60;
        }
        if (strs[2].compareTo("0") > 0) {
            min += Math.round(Float.parseFloat(strs[2]));
        }
        return min;
    }


}
